use chrono::Local;
use encoding_rs::{GBK};
use hostname::get;
use network_interface::{NetworkInterface, NetworkInterfaceConfig};
use serde::{Serialize};
use std::io::{BufRead};
use std::process::{Command, Stdio};
use serde_json::Value;
use sysinfo::{ComponentExt, CpuExt, DiskExt, System, SystemExt};
use whoami;
use winapi::um::winnt::KEY_READ;
use winreg::enums::HKEY_LOCAL_MACHINE;
use winreg::RegKey;
use ureq;

#[derive(Serialize)]
pub struct SystemInfo {
    pub device_name: String,
    pub user: String,
    pub os_info: String,
    pub system_id: String,
    pub device_type: String,
    pub cpu_usage: f32,
    pub total_memory: f64,
    pub used_memory: f64,
    pub total_disk_space: f64,
    pub available_disk_space: f64,
    pub current_time: String,
    pub pet_version: String,
    pub local_ip: String,
    pub mac_address: String,
    pub internet_connection: bool,
    pub external_ip: String,
    pub ipconfig_output: String,
}


pub fn gather_system_info() -> SystemInfo {
    let mut sys = System::new_all();
    sys.refresh_all();

    // 获取设备名
    let device_name = get().unwrap_or_default().to_string_lossy().to_string();

    // 登录用户
    let user = get_current_user();

    // 操作系统
    let os_info = whoami::distro();

    // 获取系统ID
    let system_id = get_system_id();

    // 设备类型 (简单判断是否带电池)
    sys.refresh_components_list(); // 刷新硬件组件列表
    let device_type = if sys
        .components()
        .iter()
        .any(|c| c.label().to_lowercase().contains("battery"))
    {
        "笔记本"
    } else {
        "台式机"
    };

    // CPU 使用率
    let cpu_usage = sys.global_cpu_info().cpu_usage();

    // 内存使用情况
    let total_memory = sys.total_memory() as f64 / 1024.0 / 1024.0 / 1024.0; // 转为 GB
    let used_memory = sys.used_memory() as f64 / 1024.0 / 1024.0 / 1024.0; // 转为 GB

    // 磁盘使用情况
    let total_disk_space =
        sys.disks().iter().map(|d| d.total_space()).sum::<u64>() as f64 / 1024.0 / 1024.0 / 1024.0; // 转为 GB
    let available_disk_space = sys.disks().iter().map(|d| d.available_space()).sum::<u64>() as f64
        / 1024.0
        / 1024.0
        / 1024.0; // 转为 GB

    // 获取当前时间（本地时间）
    let current_time = Local::now().format("%Y-%m-%d: %H:%M:%S").to_string();

    // 版本号
    let pet_version = "2.5.7".to_string();

    // 获取网络信息（IP 地址和 MAC 地址）
    let (mac_address, local_ip) = get_network_info();

    // 检查是否能够连接外网
    let internet_connection = check_internet_connection();

    // 获取外网 IP
    let external_ip = get_external_ip().unwrap_or_else(|| "未知".to_string());

    // 获取 ipconfig /all 输出
    let ipconfig_output = get_ipconfig_output();

    // 返回系统信息结构体
    SystemInfo {
        device_name,
        user,
        os_info,
        system_id,
        device_type: device_type.to_string(),
        cpu_usage,
        total_memory,
        used_memory,
        total_disk_space,
        available_disk_space,
        current_time,
        pet_version,
        local_ip,
        mac_address,
        internet_connection,
        external_ip,
        ipconfig_output,
    }
}

// 获取系统ID（通过 wmic 获取）
fn get_system_id() -> String {
    let output = Command::new("wmic")
        .arg("csproduct")
        .arg("get")
        .arg("UUID")
        .output()
        .expect("Failed to execute wmic command");

    let output_str = String::from_utf8_lossy(&output.stdout);
    output_str
        .lines()
        .skip(1) // 跳过第一行（标题）
        .filter(|&line| !line.trim().is_empty()) // 过滤空行
        .next()
        .unwrap_or("Unknown")
        .trim()
        .to_string()
}

// 获取网络信息：MAC 地址和 IPv4 地址
fn get_network_info() -> (String, String) {
    let output = Command::new("ipconfig")
        .arg("/all")
        .stdout(Stdio::piped())
        .output()
        .expect("Failed to execute ipconfig");

    if !output.status.success() {
        return ("Unknown".to_string(), "Unknown".to_string());
    }

    // Decode GBK output to UTF-8
    let (decoded, _, _) = GBK.decode(&output.stdout);
    let ipconfig_output = decoded.to_string();

    let mut mac_address = "Unknown".to_string();
    let mut local_ip = "Unknown".to_string();

    let mut current_adapter = "";
    let mut is_media_disconnected = false;

    for line in ipconfig_output.lines() {
        let trimmed = line.trim();

        if trimmed.starts_with("以太网适配器 以太网")
            || trimmed.starts_with("Ethernet adapter Ethernet")
        {
            current_adapter = "Ethernet";
            is_media_disconnected = false;
        } else if trimmed.starts_with("无线局域网适配器 WLAN")
            || trimmed.starts_with("Wireless LAN adapter WLAN")
        {
            if current_adapter != "Ethernet" || is_media_disconnected {
                current_adapter = "WLAN";
                is_media_disconnected = false;
            }
        } else if trimmed.contains("媒体状态") || trimmed.contains("Media State") {
            if trimmed.contains("媒体已断开连接") || trimmed.contains("Media disconnected") {
                is_media_disconnected = true;
            }
        } else if trimmed.contains("物理地址") || trimmed.contains("Physical Address") {
            if !is_media_disconnected {
                let parts: Vec<&str> = trimmed.split(':').collect();
                if parts.len() == 2 {
                    mac_address = parts[1].trim().to_string();
                }
            }
        } else if trimmed.contains("IPv4 地址") || trimmed.contains("IPv4 Address") {
            if !is_media_disconnected {
                let parts: Vec<&str> = trimmed.split(':').collect();
                if parts.len() == 2 {
                    local_ip = parts[1]
                        .trim()
                        .replace("(首选)", "")
                        .replace("(Preferred)", "")
                        .to_string();
                }
            }
        }
    }

    // 如果通过 ipconfig 获取不到有效的 IPv4 地址
    if mac_address == "Unknown" || local_ip == "Unknown" {
        let interfaces = NetworkInterface::show().unwrap();
        for iface in interfaces {
            if let Some(mac) = iface.mac_addr {
                mac_address = mac;
            }
            if let Some(addr) = iface.addr.iter().find(|a| a.ip().is_ipv4()) {
                local_ip = addr.ip().to_string();
            }
            break; // 只获取第一个有效的接口信息
        }
    }

    (mac_address, local_ip)
}

fn get_current_user() -> String {
    // 打开注册表键，获取最后登录用户的信息
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
    match hklm.open_subkey_with_flags(
        r"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI",
        KEY_READ,
    ) {
        Ok(subkey) => {
            // 读取 LastLoggedOnUser 的值
            match subkey.get_value::<String, _>("LastLoggedOnUser") {
                Ok(last_logged_on_user) => {
                    // 使用 '\\' 分割字符串，获取最后一部分（即用户名）
                    last_logged_on_user
                        .split('\\')
                        .last()
                        .unwrap_or("System!")
                        .to_string()
                }
                Err(_) => "System!".to_string(), // 如果读取失败，返回 "System!"
            }
        }
        Err(_) => "System!".to_string(), // 如果打开注册表失败，返回 "System!"
    }
}

fn check_internet_connection() -> bool {
    let output = Command::new("ping")
        .arg("-n")
        .arg("1")
        .arg("www.baidu.com")
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .output();

    match output {
        Ok(output) => output.status.success(),
        Err(_) => false, // 如果命令执行失败，认为没有网络连接
    }
}

// 获取公网 IP 地址
fn get_external_ip() -> Option<String> {
    let url = "https://ip.useragentinfo.com/json";

    // 发起 HTTP GET 请求
    match ureq::get(url).call() {
        Ok(response) => {
            if let Ok(json) = response.into_json::<Value>() {
                // 提取字段
                let ip = json["ip"].as_str().unwrap_or("未知");
                let country = json["country"].as_str().unwrap_or("");
                let province = json["province"].as_str().unwrap_or("");
                let city = json["city"].as_str().unwrap_or("");
                let isp = json["isp"].as_str().unwrap_or("");

                // 格式化输出
                Some(format!("{} {}{}{} {}", ip, country, province, city, isp))
            } else {
                eprintln!("无法解析 JSON 响应");
                None
            }
        }
        Err(e) => {
            eprintln!("请求失败: {}", e);
            None
        }
    }
}

// 获取 ipconfig /all 输出并转换为 UTF-8
fn get_ipconfig_output() -> String {
    let output = Command::new("ipconfig")
        .arg("/all")
        .stdout(Stdio::piped()) // 捕获标准输出
        .stderr(Stdio::piped()) // 捕获标准错误
        .output()
        .expect("Failed to execute ipconfig");

    if output.status.success() {
        // 使用 encoding_rs 将 GBK 转换为 UTF-8
        let (result, _, _) = GBK.decode(&output.stdout);

        // 将转换后的字节数据转换为 String
        result.to_string()
    } else {
        // 如果命令执行失败，打印错误
        String::from_utf8_lossy(&output.stderr).to_string()
    }
}
